package easy.trace.agent.log4j;

import easy.trace.agent.handle.ExceptionProtect;
import easy.trace.agent.util.ConfigurationResourcesResolver;

import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.List;

import static easy.trace.agent.util.ConfigurationResourcesResolver.DEFAULT_APPLICATION_LOG4J_FILE;

/**
 * log4j 文件追加trace配置
 *
 * @author easy
 * @data 23/05/2018.
 */
public class ConfigurationAppender {

    private ExceptionProtect callback;
    private static final String DEFAULT_LINE_BREAK = "\n";

    public ConfigurationAppender(ExceptionProtect callback) {
        this.callback = callback;
    }

    /**
     * log4j 文件比较,若不存在trace配置,则追加
     *
     * @return
     * @throws IOException
     * @throws URISyntaxException
     */
    public boolean compareAndAppend() {
        try {
            List<String> localConfigLines = ConfigurationResourcesResolver.loadLocalConfig();
            if (localConfigLines == null || localConfigLines.isEmpty()) {
                return false;
            }
            List<String> applicationConfigLines = ConfigurationResourcesResolver.loadApplicationConfig();
            if (applicationConfigLines == null || applicationConfigLines.isEmpty()) {
                return false;
            }
            URL log4jFileAbsolutePath = ConfigurationResourcesResolver.getLog4jFileAbsolutePath(DEFAULT_APPLICATION_LOG4J_FILE);
            if (log4jFileAbsolutePath == null) {
                return false;
            }

            final Path path = Paths.get(log4jFileAbsolutePath.getPath());

            localConfigLines.stream()
                    .filter(line -> {
                        String propKey = line.trim().split("=")[0];
                        if (line == null || line.length() == 0) {
                            return false;
                        }
                        return applicationConfigLines.stream()
                                .filter(app -> app.contains(propKey))
                                .count() == 0L;
                    })
                    .forEachOrdered(line -> {
                        try {
                            if (Files.exists(path)) {
                                Files.write(path, DEFAULT_LINE_BREAK.getBytes(), StandardOpenOption.APPEND);
                                Files.write(path, line.getBytes(), StandardOpenOption.APPEND);
                                System.out.println("追加文件内容:" + line);
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    });
            Files.write(path, DEFAULT_LINE_BREAK.getBytes(), StandardOpenOption.APPEND);

            return true;
        } catch (Throwable e) {
            e.printStackTrace();
            callback.handle(e);
        }
        return false;
    }
}
